﻿using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows.Threading;
using Newtonsoft.Json.Linq;
using System.Windows.Media.Imaging;

namespace BeerManagementSystem
{
    internal delegate void AddItem(BeerboxItem item);

    class BeerboxUpdater
    {
        private UriConnector _uriConnector;
        private Backend _backend;
        public event EventHandler<BeerboxEventArgs> MessageFromBeerbox;
        private DateTime _date;
        private bool _close;

        public BeerboxUpdater(UriConnector connector, Backend backend)
        {
            _backend = backend;
            _uriConnector = connector;
            _date = DateTime.Now.AddDays(-7);
            var t = new Thread(IsBeerboxOutdated) { IsBackground = true };


            if (Properties.Settings.Default.WebConnectorStatus)
            {
                t.Start();
            }
        }

        public Dispatcher Dispatcher { get; set; }

        public CheckIn CheckIn { get; set; }

        private void IsBeerboxOutdated()
        {
            var request = WebRequest.Create("http://www.schmidtwoch.com/sites/default/bms-actions/updateBeerbox.php&shaFromBMS=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
            request.Method = "POST";
            var state = new RequestState(request);

            var result = request.BeginGetResponse(UpdateBeerBox, state);

            ThreadPool.RegisterWaitForSingleObject(
                result.AsyncWaitHandle,
                ScanTimeoutCallback,
                state,
                (30 * 1000), // 30 second timeout
                true
                );

        }
         #region Time conversions

        private long ToUnixTimespan(DateTime dateTime)
        {
            var tspan = dateTime.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0));

            return (long)Math.Truncate(tspan.TotalSeconds);
        }
        #endregion
        
        private void UpdateBeerBox(IAsyncResult result)
        {
            while (!_close)
            {
                try
                {
                    long timestamp = ToUnixTimespan(_date);

                    string postData = "beerbox=[{\"timestamp\":" + timestamp + "}]&shaFromBMS=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
// ReSharper disable LocalizableElement
                    Console.WriteLine("Send Timestamp:       " + timestamp);
// ReSharper restore LocalizableElement
                    var request = (HttpWebRequest)WebRequest.Create("http://www.schmidtwoch.com/sites/default/bms-actions/updateBeerbox.php");
                    request.Method = "POST";
                    byte[] byteArray = Encoding.UTF8.GetBytes(postData);
                    // Set the ContentType property of the WebRequest.
                    request.ContentType = "application/x-www-form-urlencoded";
                    // Set the ContentLength property of the WebRequest.
                    request.ContentLength = byteArray.Length;
                    // Set the CookieContainer for the WebRequest
                    var cc = new CookieContainer();
                    request.CookieContainer = cc;
                    var dataStream = request.GetRequestStream();
                    // Write the data to the request stream.
                    dataStream.Write(byteArray, 0, byteArray.Length);
                    // Close the Stream object.
                    dataStream.Close();
                    request.Timeout = 1000;
                 
                    var response = (HttpWebResponse)request.GetResponse();
                    // Get the stream containing content returned by the server.
                    dataStream = response.GetResponseStream();
                    if (dataStream != null)
                    {
                        var reader = new StreamReader(dataStream);
                        // Read the content.
                        var responseFromServer = reader.ReadToEnd();
                        // Clean up the streams.
                        reader.Close();
                        var test = responseFromServer;
                        var jo = JObject.Parse(test);
                        Console.WriteLine(responseFromServer);
                        if(responseFromServer != "{\"Message\":[]}")
                        {
                            foreach (var jItem in jo["Message"])
                            {
                                //dateTime = ConvertFromUnixTimestamp((long) jItem["timestamp"]).AddSeconds(10);
                                _date = DateTime.Now;
                                BitmapImage mPic = null;
                                if (jItem["messageImage"].Children().Count() != 0)
                                {
                                    mPic =
                                        _uriConnector.GetMessageImage(
                                            jItem["messageImage"].Children().First().ToString());
                                }
                                var item = new BeerboxItem
                                    {
                                        Sender = _backend.GetUser((int)jItem["user"]).FirstName + " " + _backend.GetUser((int)jItem["user"]).LastName,
                                        Message = jItem["message"].ToString(),
                                        UserImage = _uriConnector.GetProfileImage(_backend.GetUser((int) jItem["user"])),
                                        MessageImage = mPic,
                                        Timestamp = _date
                                       
                                    };
                                MessageFromBeerbox(this, new BeerboxEventArgs(item));
                                _uriConnector.PlaySound("Message.wav");
                                
                            }
                        }
                        else
                        {
                            MessageFromBeerbox(this, new BeerboxEventArgs(null));
                        }
                    }

                    response.Close();
                    
                    Thread.Sleep(10000);
                    //if (i > 2) item = null;

                }
                catch (WebException e)
                {
                    
                    Console.WriteLine(e.StackTrace);
                    Console.WriteLine(e.InnerException);
                    MessageFromBeerbox(this, new BeerboxEventArgs(null));
                    Thread.Sleep(10000);
                    MessageFromBeerbox(this, new BeerboxEventArgs(null));
                    Thread.Sleep(10000);
                    MessageFromBeerbox(this, new BeerboxEventArgs(null));
                }
            
                
            }
            
        }


        private static void ScanTimeoutCallback(object state, bool timedOut)
        {
            if (timedOut)
            {
                var reqState = (RequestState)state;
                if (reqState != null)
                    reqState.Request.Abort();
            }
        }

        public void Close()
        {
            _close = true;
            LogWriter.Write("BeerboxUpdtaer: wurde geschlossen", LogWriter.LogLevel.Status, this);
        }
    }

    internal class RequestState
    {
        public RequestState(WebRequest request)
        {
            Request = request;
        }

        public WebRequest Request { get; set; }
    }

    class BeerboxResponse
    {
        public int User { get; set; }
        public string Message { get; set; }
        public long Timestamp { get; set; }
        public string MessageImage { get; set; }

    }
}
